package com.ajie.config.redis;

import com.ajie.entity.Course;
import com.ajie.entity.LookLikeFavourite;
import com.ajie.entity.Moment;
import com.ajie.entity.New;
import com.ajie.service.CourseService;
import com.ajie.service.MomentService;
import com.ajie.service.NewService;
import com.ajie.service.SysUserService;
import com.ajie.utils.DateUtils;
import com.ajie.utils.JedisUtils;
import com.ajie.utils.RedisUtil;
import com.ajie.vo.MomentVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Slf4j
@Component
@EnableScheduling
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ListenHandler {
    
    @Autowired
    private final MomentService momentService;
    
    @Autowired
    private final NewService newService;
    
    
    @Autowired
    private final CourseService courseService;
    
    @Autowired
    private final SysUserService userService;
    
    @Autowired
    private final RedisUtil redisUtil;
    
    @Autowired
    private final JedisUtils jedisUtils;
    
    private static final String LOOK_KEY = "looks";
    private static final String LIKE_KEY = "likes";
    private static final String FAVOURITE_KEY = "favourites";
    
    
    @Autowired
    public ListenHandler(MomentService momentService,NewService newService,CourseService courseService ,SysUserService userService, RedisUtil redisUtil,JedisUtils jedisUtils) {
        this.momentService = momentService;
        this.newService = newService;
        this.courseService = courseService;
        this.redisUtil = redisUtil;
        this.userService = userService;
        this.jedisUtils = jedisUtils;
    }
    
    @PostConstruct
    public void init() throws Exception {
        log.info("数据初始化开始...");
        //将数据库中的数据写入redis
        List<MomentVo> momentList = momentService.getAll();
        List<New> newList = newService.getAll();
        List<Course> courseList = courseService.getAll();
        List<LookLikeFavourite> list = userService.findLookLikeFavourite();
        System.out.println(list);
        if (list.size() > 0){
            list.forEach(item->{
                if (item.getLook()){
                    redisUtil.sSet( item.getResourceType()+ "Id::"+item.getResourceId().toString(), "look::userId::"+ item.getUid()+"::createTime::"+item.getLookTime());
                }
                if (item.getLike()){
                    redisUtil.sSet( item.getResourceType()+ "Id::"+item.getResourceId().toString(), "like::userId::"+ item.getUid()+"::createTime::"+item.getLikeTime());
                }
                if (item.getFavourite()){
                    redisUtil.sSet( item.getResourceType()+ "Id::"+item.getResourceId().toString(), "favourite::userId::"+ item.getUid()+"::createTime::"+item.getFavouriteTime());
                }
            });
        }
        for (New new1: newList ){
            redisUtil.zAdd(LOOK_KEY, "new::" + new1.getId().toString(), new1.getLookNum());
            redisUtil.zAdd(LIKE_KEY,"new::" + new1.getId().toString(),new1.getLikeNum());
            redisUtil.zAdd(FAVOURITE_KEY,"new::" + new1.getId().toString(),new1.getFavouriteNum());
        }
        for (MomentVo moment: momentList ){
            redisUtil.zAdd(LOOK_KEY, "moment::" + moment.getId().toString(), moment.getLookNum());
            redisUtil.zAdd(LIKE_KEY,"moment::" + moment.getId().toString(),moment.getLikeNum());
            redisUtil.zAdd(FAVOURITE_KEY,"moment::" + moment.getId().toString(),moment.getFavouriteNum());
        }
        for (Course course: courseList ){
            redisUtil.zAdd(LOOK_KEY, "course::" + course.getId().toString(), course.getLookNum());
            redisUtil.zAdd(LIKE_KEY,"course::" + course.getId().toString(),course.getLikeNum());
            redisUtil.zAdd(FAVOURITE_KEY,"course::" + course.getId().toString(),course.getFavouriteNum());
        }
        log.info("数据已写入redis...");
    }
    
    
    @Scheduled(cron = "* */20 * * * ?")
    public void updateNum() {
        log.info("周期任务开始执行...");
        writeNum();
        
        
        // courseList.forEach(item->{
        //     //2.遍历redis，查看是否存在某一条动态有点赞收藏或浏览
        //     Boolean b = redisUtil.haskey("courseId::" + item.getId());
        //     //3.如果有
        //     if (b) {
        //         // 3.1 获取mysql中resourceID == id 并且resourceType == moment的  resourceID == id 、resourceType == moment、和userId
        //         LookLikeFavourite lookLikeFavourite2 = new LookLikeFavourite();
        //         lookLikeFavourite2.setResourceType("course");
        //         lookLikeFavourite2.setResourceId(item.getId());
        //         LookLikeFavourite lookLikeFavourite1 = userService.findLookLikeFavouriteByReid(lookLikeFavourite2);
        //         if (lookLikeFavourite1 == null){
        //             Set<Object> courseSet = redisUtil.sGet("courseId::"+item.getId());
        //             courseSet.forEach(item1->{
        //                 String[] split = item1.toString().split("::");
        //                 log.info("split为=>{},=>{},=>{}",split[0],split[1],Long.valueOf(split[2]));
        //                 LookLikeFavourite lookLikeFavourite3 = new LookLikeFavourite();
        //                 lookLikeFavourite3.setResourceType("course");
        //                 lookLikeFavourite3.setResourceId(item.getId());
        //                 lookLikeFavourite3.setUid(Long.valueOf(split[2]));
        //                 userService.insertLookLikeFavouriteByReid(lookLikeFavourite3);
        //             });
        //             lookLikeFavourite1 = userService.findLookLikeFavouriteByReid(lookLikeFavourite2);
        //         }
        //         // 3.2 判断上面数据在redis中是否存在
        //         Boolean b1 = redisUtil.sHasKey("courseId::"+lookLikeFavourite1.getResourceId(),"look::userId::"+lookLikeFavourite1.getUid());
        //         Boolean b2 = redisUtil.sHasKey("courseId::"+lookLikeFavourite1.getResourceId(),"like::userId::"+lookLikeFavourite1.getUid());
        //         Boolean b3 = redisUtil.sHasKey("courseId::"+lookLikeFavourite1.getResourceId(),"favourite::userId::"+lookLikeFavourite1.getUid());
        //         //3.3 存在的话赋值为1，不存在为0
        //         lookLikeFavourite1.setLook(b1);
        //         lookLikeFavourite1.setLike(b2);
        //         lookLikeFavourite1.setFavourite(b3);
        //         userService.updateLookLikeFavourite(lookLikeFavourite1);
        //         //4.如果没有
        //     }else{
        //         LookLikeFavourite lookLikeFavourite1 = new LookLikeFavourite();
        //         lookLikeFavourite1.setResourceId(item.getId());
        //         lookLikeFavourite1.setResourceType("course");
        //         LookLikeFavourite lookLikeFavourite = userService.findLookLikeFavouriteByReid(lookLikeFavourite1);
        //         if (lookLikeFavourite != null){
        //             userService.delLookLikeFavourite(lookLikeFavourite1);
        //         }
        //     }
        // });
        
        log.info("周期任务执行完毕,redis写入数据库完毕");
    }
    
    private void writeNum() {
        //1.取动态表中所有id
        List<MomentVo> momentList = momentService.getAll();
        List<New> newList = newService.getAll();
        List<Course> courseList = courseService.getAll();
        //清除表所有信息
        userService.delLookLikeFavourite();
        userService.reset();
        //1.取动态表中所有id
        momentList.forEach(item->{
            LookLikeFavourite LLF1 = new LookLikeFavourite();
            LLF1.setResourceType("moment");
            LLF1.setResourceId(item.getId());
            //2.到redis中取出所有momentId的所有信息
            Set<Object> momentSet = redisUtil.sGet("momentId::"+item.getId());
            //如果非空，遍历
            if (momentSet != null){
                //遍历
                List<String> list = new ArrayList<>();
                momentSet.forEach(item2->{
                    String[] split = item2.toString().split("::");
                    //整理数据到对象上
                    if (!list.contains(split[2])){
                        list.add(split[2]);
                    }
                });
                list.forEach(id->{
                    momentSet.forEach(item2->{
                        //整理数据到对象上
                        String[] split = item2.toString().split("::");
                        Long uid = Long.valueOf(split[2]);
                        LLF1.setUid(uid);
                        if (id.equals(uid.toString())){
                            String createTime = split[4];
                            System.out.println(createTime+"111111111111111111");
                            String type = split[0];
                            if ("look".equals(type)){
                                LLF1.setLook(true);
                                LLF1.setLookTime(createTime);
                            } else if ("like".equals(type)) {
                                LLF1.setLike(true);
                                LLF1.setLikeTime(createTime);
                            } else if ("favourite".equals(type)) {
                                LLF1.setFavourite(true);
                                LLF1.setFavouriteTime(createTime);
                            }
                        }
                    });
                    if (LLF1.getLook() == null) {
                        LLF1.setLook(false);
                    }
                    if (LLF1.getLike() == null) {
                        LLF1.setLike(false);
                    }
                    if (LLF1.getFavourite() == null) {
                        LLF1.setFavourite(false);
                    }
                    userService.insertLookLikeFavouriteByReid(LLF1);
                });
                
            }
            Moment moment = new Moment();
            moment.setId(item.getId());
            Long lookNum = jedisUtils.zscore(LOOK_KEY,"moment::"+item.getId()).longValue();
            Long likeNum = jedisUtils.zscore(LIKE_KEY,"moment::"+item.getId()).longValue();
            Long favouriteNum = jedisUtils.zscore(FAVOURITE_KEY,"moment::"+item.getId()).longValue();
            moment.setLookNum(lookNum);
            moment.setLikeNum(likeNum);
            moment.setFavouriteNum(favouriteNum);
            momentService.update(moment);
        
        });
    
        newList.forEach(item->{
            LookLikeFavourite LLF1 = new LookLikeFavourite();
            LLF1.setResourceType("new");
            LLF1.setResourceId(item.getId());
            //2.到redis中取出所有momentId的所有信息
            Set<Object> newSet = redisUtil.sGet("newId::"+item.getId());
            //如果非空，遍历
            if (newSet != null) {
                //遍历
                List<String> list = new ArrayList<>();
                newSet.forEach(item2 -> {
                    //拆分数据  look/like/favourite + userid
                    String[] split = item2.toString().split("::");
                    if (!list.contains(split[2])) {
                        list.add(split[2]);
                    }
                });
                list.forEach(id -> {
                    newSet.forEach(item2 -> {
                        //整理数据到对象上
                        String[] split = item2.toString().split("::");
                        Long uid = Long.valueOf(split[2]);
                        LLF1.setUid(uid);
                        if (id.equals(uid.toString())) {
                            String createTime = split[4];
                            String type = split[0];
                            if ("look".equals(type)) {
                                LLF1.setLook(true);
                                LLF1.setLookTime(createTime);
                            } else if ("like".equals(type)) {
                                LLF1.setLike(true);
                                LLF1.setLikeTime(createTime);
                            } else if ("favourite".equals(type)) {
                                LLF1.setFavourite(true);
                                LLF1.setFavouriteTime(createTime);
                            }
                        }
                    });
                    if (LLF1.getLook() == null) {
                        LLF1.setLook(false);
                    }
                    if (LLF1.getLike() == null) {
                        LLF1.setLike(false);
                    }
                    if (LLF1.getFavourite() == null) {
                        LLF1.setFavourite(false);
                    }
                    userService.insertLookLikeFavouriteByReid(LLF1);
                });
                Long lookNum = jedisUtils.zscore(LOOK_KEY, "new::" + item.getId()).longValue();
                Long likeNum = jedisUtils.zscore(LIKE_KEY, "new::" + item.getId()).longValue();
                Long favouriteNum = jedisUtils.zscore(FAVOURITE_KEY, "new::" + item.getId()).longValue();
                item.setLookNum(lookNum);
                item.setLikeNum(likeNum);
                item.setFavouriteNum(favouriteNum);
                newService.update(item);
            }
        });

        courseList.forEach(item->{
            LookLikeFavourite LLF1 = new LookLikeFavourite();
            LLF1.setResourceType("course");
            LLF1.setResourceId(item.getId());
            //2.到redis中取出所有momentId的所有信息
            Set<Object> courseSet = redisUtil.sGet("courseId::"+item.getId());
            //如果非空，遍历
            if (courseSet != null) {
                //遍历
                List<String> list = new ArrayList<>();
                courseSet.forEach(item2 -> {
                    //拆分数据  look/like/favourite + userid
                    String[] split = item2.toString().split("::");
                    if (!list.contains(split[2])) {
                        list.add(split[2]);
                    }
                });
                list.forEach(id -> {
                    courseSet.forEach(item2 -> {
                        //整理数据到对象上
                        String[] split = item2.toString().split("::");
                        Long uid = Long.valueOf(split[2]);
                        LLF1.setUid(uid);
                        if (id.equals(uid.toString())) {
                            String createTime = split[4];
                            System.out.println(createTime + "111111111111111111");
                            String type = split[0];
                            if ("look".equals(type)) {
                                LLF1.setLook(true);
                                LLF1.setLookTime(createTime);
                            } else if ("like".equals(type)) {
                                LLF1.setLike(true);
                                LLF1.setLikeTime(createTime);
                            } else if ("favourite".equals(type)) {
                                LLF1.setFavourite(true);
                                LLF1.setFavouriteTime(createTime);
                            }
                        }
                    });
                    if (LLF1.getLook() == null) {
                        LLF1.setLook(false);
                    }
                    if (LLF1.getLike() == null) {
                        LLF1.setLike(false);
                    }
                    if (LLF1.getFavourite() == null) {
                        LLF1.setFavourite(false);
                    }
                    userService.insertLookLikeFavouriteByReid(LLF1);
                });
            }
            Long lookNum = jedisUtils.zscore(LOOK_KEY,"course::"+item.getId()).longValue();
            Long likeNum = jedisUtils.zscore(LIKE_KEY,"course::"+item.getId()).longValue();
            Long favouriteNum = jedisUtils.zscore(FAVOURITE_KEY,"course::"+item.getId()).longValue();
            item.setLookNum(lookNum);
            item.setLikeNum(likeNum);
            item.setFavouriteNum(favouriteNum);
            courseService.update(item);
        });
        log.info("{} 更新完毕");
    }
    
    
    /**
     * 关闭时操作
     */
    @PreDestroy
    public void afterDestroy()  {
        log.info("开始关闭...");
        //将redis中的数据写入数据库
        writeNum();
        log.info("redis写入数据库完毕");
    }
    
}